<script setup lang="ts">
import type Typings from "@/typings";
import { computed, nextTick, ref } from "vue";
import Validate from "@/validate";
import { $singleMsg } from "@/utils/element";
import service from "@/apis";

const dialogMode = ref("view");

// 是否查看模式
const isView = computed(() => {
    return ["view"].includes(dialogMode.value);
});

// 表单内容
const formData = ref<Partial<Typings.Button.props>>({
    id: "",
    parentKey: "",
    title: "",
    key: "",
});

const visible = ref<boolean>(false);
const resolve = ref();
const reject = ref();
const form = ref();
// 控制器操作
const controller = {
    // 打开弹窗
    open: async (
        data: Partial<Typings.Button.props> = {},
        mode: Typings.Common.modeType = "view"
    ) => {
        return new Promise((_resolve, _reject) => {
            visible.value = true;
            resolve.value = _resolve;
            reject.value = _reject;

            formData.value = { ...formData.value, ...data };
            dialogMode.value = mode;

            nextTick(() => {
                form.value.clearValidate();
            });
        });
    },

    // 关闭弹窗
    close: (shouldReject = true) => {
        visible.value = false;

        formData.value = {
            id: "",
            parentKey: "",
            title: "",
            key: "",
        };

        if (shouldReject) {
            reject.value(new Error("关闭弹窗"));
        }
    },

    validate: async () => {
        try {
            await form.value.validate();
            return Promise.resolve(true);
        } catch (err) {
            console.log(err);
            const tip = "请完善表单";
            $singleMsg({ message: tip, type: "warning" });
            return Promise.reject(new Error(tip));
        }
    },

    confirm: async () => {
        await controller.validate();

        const apiService = {
            add: service.buttonAddApi,
            update: service.buttonUpdateApi,
        } as const; // 使用 as const 确保字面量类型

        await apiService[dialogMode.value as keyof typeof apiService](
            formData.value
        );

        $singleMsg({ message: "操作成功" });

        resolve.value(true);

        controller.close(false);
    },
};

defineExpose({
    open: controller.open,
});
</script>

<template>
    <xt-dialog width="520px" v-model="visible" title="菜单信息" :before-close="controller.close">
        <el-form ref="form" :model="formData" label-width="108px" :disabled="isView">
            <el-row :gutter="20">
                <el-col>
                    <el-form-item label="页面Key值" prop="parentKey">
                        <xt-input v-model="formData.parentKey" disabled />
                    </el-form-item>
                </el-col>
                <el-col>
                    <el-form-item label="名称" prop="title" :rules="Validate.Required()">
                        <xt-input v-model="formData.title" />
                    </el-form-item>
                </el-col>
                <el-col>
                    <el-form-item label="Key值" prop="key" :rules="Validate.Required()">
                        <xt-input v-model="formData.key" />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>

        <template #footer>
            <div>
                <xt-button @click="controller.confirm" v-if="!isView">确 定</xt-button>
                <xt-button type="default" @click="controller.close(true)">取 消</xt-button>
            </div>
        </template>
    </xt-dialog>
</template>
